R Package Dependencies


In [160]:
import pandas
import networkx 

from matplotlib import pyplot as plt

%matplotlib inline
from IPython.display import set_matplotlib_formats
#set_matplotlib_formats('pdf')

data = pandas.DataFrame.from_csv('../data/github-cran-150601.csv')
data['Date'] = pandas.to_datetime(data['Date'])
data = data.sort('Date')

In [161]:
R_packages = ('R MASS Matrix base boot class cluster codetools compiler datasets foreign grDevices ' +
        'graphics grid lattice methods mgcv nlme nnet parallel rpart ' +
        'spatial splines stats stats4 survival tcltk tools translations utils').split(' ')

In [162]:
def data_for_date(data, date):
    return data.query('InCRAN == 1 and Date <= "{date}"'.format(date=date)).drop_duplicates(('Package'), take_last=True).fillna('').set_index('Package', inplace=False)

In [163]:
def graph_for_data(data, ignore_R = True):
    G = networkx.DiGraph()
    G.add_nodes_from(list(data.index))
    for index, row in data.iterrows():
        deps = row['Dependencies'].split(' ')
        for dep in deps: 
            if dep in data.index:
                G.add_edge(index, dep)
    if ignore_R:
        G.remove_nodes_from(R_packages)
    return G

In [164]:
def nodes_properties(G):
    isolated = networkx.isolates(G)

    for node in networkx.topological_sort(G, reverse=True):
        min_strata = len(G.node) + 1
        max_strata = 0
        for successor in G.successors(node):
            if G.node[successor]['max_strata'] > max_strata:
                max_strata = G.node[successor]['max_strata']
            if G.node[successor]['min_strata'] < min_strata:
                min_strata = G.node[successor]['min_strata']
        if min_strata == len(G.node) + 1:
            min_strata = 0
        G.node[node]['min_strata'] = min_strata + 1
        G.node[node]['max_strata'] = max_strata + 1

    packages = pandas.DataFrame.from_dict({n: {'ancestors': len(networkx.ancestors(G, n)),
                                    'descendants': len(networkx.descendants(G, n)),
                                    'out': G.out_degree(n), 
                                    'in': G.in_degree(n),
                                    'isolated': n in isolated,
                                    'min_strata': G.node[n]['min_strata'],
                                    'max_strata': G.node[n]['max_strata']} for n in G.nodes_iter()}, orient='index')
    return packages

In [165]:
dates = pandas.date_range(start='2010-01', end='2015-01', freq='3M')

In [166]:
from collections import OrderedDict

summary = OrderedDict()
graphs = OrderedDict()
props = OrderedDict()

for date in dates:     
    G = graph_for_data(data_for_date(data, date))
    p = nodes_properties(G)
    
    d = OrderedDict()
    d['nodes'] = len(G)

    nonisolated = p.query('isolated == False')
    d['nonisolated'] = len(nonisolated)
    
    d['max ancestors'] = nonisolated['ancestors'].max()
    d['max descendants'] = nonisolated['descendants'].max()
    
    #d['min_strata mean'] = nonisolated['min_strata'].mean()
    #d['max_strata mean'] = nonisolated['max_strata'].mean()
    
    d['min_strata <= 1'] = len(nonisolated.query('min_strata <= 1'))
    d['max_strata <= 1'] = len(nonisolated.query('max_strata <= 1'))
                                                 
    d['min_strata >= 3'] = len(nonisolated.query('min_strata >= 3'))
    d['max_strata >= 3'] = len(nonisolated.query('max_strata >= 3'))
    
    summary[date] = d
    graphs[date] = G
    props[date] = p

In [167]:
df = pandas.DataFrame.from_dict(summary, orient='index')
df.index = pandas.to_datetime(df.index)

ax = df.plot(style=[None, None, None, None, '--', '--', '--', '--'], title='CRAN Packages')
ax.figure.set_size_inches(16, 8)



In [168]:
df = pandas.DataFrame.from_dict({date: p.query('isolated == False')['min_strata'] for date, p in props.iteritems()})

ax = df.plot(title='Minimal Strata Distribution for CRAN Packages', kind='box')
ax.figure.set_size_inches(16, 4)

df = pandas.DataFrame.from_dict({date: p.query('isolated == False')['max_strata'] for date, p in props.iteritems()})

ax = df.plot(title='Maximal Strata Distribution for CRAN Packages', kind='box')
ax.figure.set_size_inches(16, 4)

df = pandas.DataFrame.from_dict({date: p.query('isolated == False')['descendants'] for date, p in props.iteritems()})

ax = df.plot(title='Descendants Distribution for CRAN Packages', kind='box')
ax.figure.set_size_inches(16, 4)

df = pandas.DataFrame.from_dict({date: p.query('isolated == False')['ancestors'] for date, p in props.iteritems()})

ax = df.plot(title='Ancestors Distribution for CRAN Packages', kind='box')
ax.figure.set_size_inches(16, 4)



In [169]:
df.sort('2014-07-31 00:00:00', ascending=False, inplace=False)


Out[169]:
2010-01-31 00:00:00 2010-04-30 00:00:00 2010-07-31 00:00:00 2010-10-31 00:00:00 2011-01-31 00:00:00 2011-04-30 00:00:00 2011-07-31 00:00:00 2011-10-31 00:00:00 2012-01-31 00:00:00 2012-04-30 00:00:00 2012-07-31 00:00:00 2012-10-31 00:00:00 2013-01-31 00:00:00 2013-04-30 00:00:00 2013-07-31 00:00:00 2013-10-31 00:00:00 2014-01-31 00:00:00 2014-04-30 00:00:00 2014-07-31 00:00:00 2014-10-31 00:00:00
Rcpp 3 11 15 19 28 30 42 56 80 89 100 126 148 169 189 266 305 768 869 991
plyr 28 37 47 62 68 78 89 111 131 153 183 220 210 240 268 317 360 446 501 575
RColorBrewer 22 32 36 46 53 63 75 96 111 118 134 154 176 202 217 253 383 437 478 575
stringr 0 0 1 10 11 15 20 30 34 104 125 150 183 211 240 275 319 399 464 549
mvtnorm 126 133 141 154 171 191 211 225 236 260 280 325 349 348 362 386 395 420 440 503
digest 28 34 41 52 56 61 77 90 103 111 128 149 178 215 235 269 324 382 437 519
colorspace 27 32 53 58 64 78 94 112 127 129 142 159 194 225 241 264 307 351 383 444
reshape2 NaN NaN NaN 0 0 4 6 7 10 71 80 97 120 135 153 184 214 295 338 391
bitops 27 28 30 38 45 56 63 77 90 107 119 153 178 182 200 222 246 292 332 328
zoo 56 60 68 85 94 102 115 126 134 140 149 170 187 200 217 242 251 272 297 388
proto 15 22 27 33 36 41 50 58 73 74 82 100 118 135 146 172 209 254 286 328
dichromat NaN NaN NaN NaN NaN NaN NaN 1 1 65 75 90 106 122 135 161 200 244 277 322
labeling NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 89 105 121 134 160 199 243 276 321
munsell 0 0 0 0 0 0 0 1 1 64 74 89 105 121 134 160 199 243 276 321
scales NaN NaN NaN NaN NaN NaN NaN 0 0 63 73 88 104 120 133 159 198 242 275 320
gtable NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 84 100 115 128 153 191 235 266 309
ggplot2 8 14 18 23 26 30 39 49 59 61 68 83 99 114 127 152 190 234 265 308
sp 48 54 59 68 73 83 90 100 113 128 141 152 162 178 192 201 221 242 256 279
coda 60 68 69 74 78 83 85 91 98 114 131 151 165 188 193 199 212 223 242 254
gtools 53 57 60 60 67 81 83 90 94 102 111 120 130 140 149 166 175 186 210 226
igraph 14 17 18 23 33 38 44 52 64 72 57 70 87 113 132 154 160 176 199 217
Formula 6 7 9 12 12 12 13 15 16 19 21 25 27 34 138 148 157 171 190 248
RCurl 8 8 9 13 16 18 23 30 40 49 55 79 92 87 100 114 130 154 179 213
XML 20 21 26 28 33 39 46 53 61 70 79 92 93 106 116 130 138 151 171 196
quadprog 23 24 24 28 31 37 42 53 57 65 69 90 101 108 120 127 126 141 159 159
KernSmooth 28 28 28 29 32 32 34 66 69 82 91 96 112 124 133 136 140 151 158 166
abind 18 22 24 24 26 27 32 34 38 54 61 67 71 80 87 125 131 142 154 213
latticeExtra 2 2 1 2 2 3 3 8 9 10 13 14 15 20 20 21 127 137 154 213
car 43 50 50 51 61 70 75 77 81 90 100 115 129 138 150 114 135 142 150 189
gdata 32 34 36 37 43 51 53 60 63 73 79 86 96 103 110 124 130 136 144 153
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
survAccuracyMeasures NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
sweidnumbr NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
swfscMisc NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
synthpop NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
testthatsomemore NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
time NaN NaN 1 1 1 1 1 1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
tlemix 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 NaN NaN NaN NaN NaN
tlnise 2 2 2 2 2 2 2 2 2 2 2 2 2 1 NaN NaN NaN NaN NaN NaN
tpe NaN NaN NaN NaN NaN NaN NaN NaN NaN 0 0 0 0 NaN NaN NaN NaN NaN NaN NaN
traj NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
trajectories NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
treeclim NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
treelet NaN 0 0 0 0 0 0 0 0 0 0 NaN NaN NaN NaN NaN NaN NaN NaN NaN
trimcluster NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 11
trio 0 0 0 0 0 0 0 0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
tsModel 1 1 1 1 1 1 1 1 1 1 1 1 1 0 NaN NaN NaN NaN NaN NaN
tvd NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
twiddler NaN NaN NaN NaN NaN NaN NaN NaN NaN 1 1 1 1 1 1 NaN NaN NaN NaN NaN
uskewFactors NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
utility NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1
vcrpart NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
vdmR NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
vegan3d NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
vetools NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
virtualspecies NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
visova NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
webutils NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
wildlifeDI NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
windex NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 0
zoom NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN 1

5022 rows × 20 columns

Strata for Newly Added R Packages


In [180]:
old_packages = props[props.keys()[0]]

new_data_index = []
new_data = []

for date, ddata in props.iteritems():
    for package, metadata in ddata.iterrows():
        if package not in old_packages.index:
            new_data_index.append(package)
            metadata['snapshot_date'] = date
            new_data.append(metadata)

In [181]:
df = pandas.DataFrame(new_data, index=new_data_index)
df['snapshot_date'] = pandas.to_datetime(df['snapshot_date'])

In [182]:
github = data.query('InGitHub == 1').drop_duplicates('Package')

In [185]:
ndf = github.set_index('Package')[['InGitHub']].join(df, how='right')
ndf = ndf.fillna({'InGitHub': 0})

In [215]:
groups_GH = ndf.query('InGitHub == 1')[['min_strata', 'max_strata', 'snapshot_date']].groupby(by=['snapshot_date'])
groups_CRAN = ndf.query('InGitHub == 0')[['min_strata', 'max_strata', 'snapshot_date']].groupby(by=['snapshot_date'])

In [223]:
ax = (groups_GH.mean().rename(columns={'min_strata': 'min_strata_GH', 'max_strata': 'max_strata_GH'})
      .plot(title='New Packages Strata Average', style=['g', 'r']))
(groups_CRAN.mean().rename(columns={'min_strata': 'min_strata_CRAN', 'max_strata': 'max_strata_CRAN'})
 .plot(ax=ax, style=['b--', 'y--']))
ax.set_xlabel('Date')

ax.figure.set_size_inches(16, 6)



In [ ]: